# -*- coding: utf-8 -*-
from __future__ import absolute_import
import logging
import json

from async.celery import app
from common.push.handler import push_msg


_LOGGER = logging.getLogger('worker')


@app.task(name='common.generate_track_detail')
def generate_track_detail(track_id):
    from common.lottery.db import generate_track_detail
    try:
        generate_track_detail(track_id)
    except Exception as e:
        _LOGGER.exception('generate track [%s] detail error %s', track_id, str(e))


@app.task(name='common.send_authcode')
def send_authcode(phone, code, country):
    from common.third.sms.helper import send_sms

    send_sms([phone], 'auth_code', {'code': code}, country=country)
    _LOGGER.info('async send sms succ for phone %s', phone)


@app.task(name='common.stats_recharge')
def stats_recharge(pay_id):
    from common.campaign import moist
    from common.campaign import wheel
    from common.campaign import daily_recharge
    from common.pay.db import get_pay

    pay = get_pay(pay_id)
    user_id = pay.user_id
    price = int(pay.price)
    _LOGGER.info('stats recharge %s:%s,%s', pay_id, user_id, price)
    if price > 0:
        moist.add_new_recharge(user_id, price)
        wheel.add_wheel_task(user_id, price)
        daily_recharge.add_new_recharge(user_id, price)


def generate_term_detail(terms):
    term_count = len(terms)
    if term_count == 1:
        return term_count, terms[0]

    terms = [int(term) for term in terms]
    terms.sort()

    _list = []
    base_num = None
    for k, v in enumerate(terms):
        if base_num is None:
            base_num = v
            continue
        if v - terms[k - 1] == 1 and k < len(terms) - 1:
            continue
        else:
            if base_num == terms[k - 1]:
                _list.append(str(base_num))
            else:
                _list.append('%s~%s' % (base_num, terms[k - 1]))
            base_num = v

    return term_count, ','.join(_list)


@app.task(name='activity.stats_refund')
def stats_refund(user_id, activity_type, bet_type, terms, total_price, refund_type):
    from common.lottery.cyclical.abstract.order import REFUND_TYPE
    from common.lottery import LOTTERY_TYPE
    from common.lottery.cyclical.model import BET_TYPE_DICT
    from common.notification.handler import notify_refund

    assert isinstance(terms, (tuple, list))
    if not terms:
        return
    activity_name = LOTTERY_TYPE.get_label(activity_type)
    bet_name = BET_TYPE_DICT[activity_type].get_label(bet_type)
    total_price = str(total_price)
    refund_name = u'中奖后停追' if refund_type == REFUND_TYPE.STOP_TRACK else u'手动停止追号'
    term_count, term_detail = generate_term_detail(terms)
    info = {
        'refund_type': refund_name,
        'term_count': term_count,
        'terms': term_detail,
        'price': total_price,
        'activity_type': activity_name,
        'bet_type': bet_name
    }
    notify_refund(user_id, info)


@app.task(name='activity.stats_withdraw')
def stats_withdraw(withdraw_ids):
    from common.transaction.db import get_withdraw
    from common.notification.handler import (
        notify_withdraw_success, notify_withdraw_back)
    from common.transaction.model import WITHDRAW_TYPE, WITHDRAW_STATUS
    from common.utils.tz import utc_to_local_str

    assert isinstance(withdraw_ids, (tuple, list))
    for withdraw_id in withdraw_ids:
        withdraw = get_withdraw(withdraw_id)
        if withdraw and withdraw.status == WITHDRAW_STATUS.DONE:
            info = {}
            info['price'] = str(withdraw.price)
            info['target'] = WITHDRAW_TYPE.get_label(withdraw.target_type)
            info['date_str'] = utc_to_local_str(withdraw.created_at)
            try:
                notify_withdraw_success(withdraw.user_id, info)
            except Exception as e:
                _LOGGER.exception('notify withdraw error, withdraw_id:%s' % withdraw_id)
        if withdraw and withdraw.status == WITHDRAW_STATUS.BACK:
            info = {}
            info['target'] = WITHDRAW_TYPE.get_label(withdraw.target_type)
            info['date_str'] = utc_to_local_str(withdraw.created_at)
            info['reason'] = json.loads(withdraw.extend)['back_reason']
            info['price'] = str(withdraw.price)
            try:
                notify_withdraw_back(withdraw.user_id, info)
            except Exception as e:
                _LOGGER.exception('notify withdraw error, withdraw_id:%s' % withdraw_id)


@app.task(name='activity.stats_order_win')
def stats_order_win(order_id, activity_type):
    from common.show import db as show_db
    from common.lottery.cyclical.model import ORDER_MODEL
    from common.lottery.cyclical import ORDER_STATUS
    from common.scrolling.handler import spread
    from common.account.db.account import get_account
    from common.notification.handler import notify_win
    from common.lottery import LOTTERY_TYPE
    from common.lottery.cyclical.model import BET_TYPE_DICT

    order_table = ORDER_MODEL[activity_type]
    order = order_table.query.filter(order_table.id == order_id).one()
    assert order.status in (ORDER_STATUS.WINNED, ORDER_STATUS.UNCHECK)
    account = get_account(order.user_id)

    try:
        info = {}
        info['price'] = str(order.win_price + order.bonus)
        info['term'] = order.term
        info['activity_type'] = LOTTERY_TYPE.get_label(activity_type)
        info['bet_type'] = BET_TYPE_DICT[activity_type].get_label(order.bet_type)
        notify_win(order.user_id, order.status, info)
    except Exception as e:
        _LOGGER.exception('notify win error, order_id:%s, activity_type:%s' % (order_id, activity_type))

    # 中奖或审核后才添加跑马灯，添加晒单
    if order.status != ORDER_STATUS.WINNED:
        return

    try:
        spread(account.user_name, order.win_price)
    except Exception as e:
        _LOGGER.exception('spread scrolling error, order_id:%s, activity_type:%s' % (order_id, activity_type))

    try:
        show_db.create_show(order, activity_type)
    except Exception as e:
        _LOGGER.exception('create show error, order_id:%s, activity_type:%s' % (order_id, activity_type))
